#!/usr/bin/env python  
# -*- coding: utf-8 -*-  

#
#   Very simple python FUSE tarFS
#
#
#
#   Mostly Complete, Working
#   ToDo: filesystem stats, possibly allow adding of file
#   Fix issue so I dont have to scan most all the entries in the tar every time
#


import errno  
import fuse  
import stat  
import time  
import os, getopt, sys, tarfile
  
fuse.fuse_python_api = (0, 2)  
  
class MyFS(fuse.Fuse): 
    def __init__(self, *args, **kw): 
        self.tarFile = kw['tar']
        del(kw['tar'])
        fuse.Fuse.__init__(self, *args, **kw)  
        self.tfO = tarfile.open(name=self.tarFile, mode="r")
        self.tarMembers = self.tfO.getmembers()
        self.CACHE=dict()
        for i in self.tarMembers:
            if i.isdir() == True:
                self.CACHE[os.path.normpath(i.name)]=i
        for i in self.tarMembers:
            if i.isfile() == True:
                tmp = os.path.normpath(i.name)
                self.CACHE[tmp]=i
        print self.CACHE

    def getattr(self, path):  
        st = fuse.Stat()
        if path == "/":
            st.st_mode = stat.S_IFDIR | 0777
            st.st_nlink = 2
            st.st_atime = int(time.time())
            st.st_mtime = int(time.time())
            st.st_ctime = int(time.time())
            st.st_size = 0
        else:
            if path[1:] not in self.CACHE:
                return -errno.ENOENT
            i = self.CACHE[path[1:]]
            if i.isfile() == True:
                st.st_mode = stat.S_IFREG | 0 | i.mode
                st.st_nlink = 1
            elif i.isdir() == True:
                st.st_mode = stat.S_IFDIR | 0 | i.mode
                st.st_nlink = 2
            st.st_atime = i.mtime
            st.st_mtime = i.mtime
            st.st_ctime = i.mtime
            st.st_size = i.size
        return st

    def readdir(self, path, offset):  
        send=['.','..']
        path = path[1:]
        l = []
        for i in self.CACHE:
            l.append(i)
        for i in l:
            if len(path) == 0:
                if i.find("/") == -1:
                    send.append(i)
            else:
                if i[:len(path)+1] == "%s/"%path and i[len(path)+1:].find("/") == -1 and len(i[len(path)+1:]) > 0:
                    send.append(i[len(path)+1:])
        for x in send:
            yield fuse.Direntry(x)

    def mkdir(self, path, mode):
        return -errno.EPERM

    def rmdir(self, path):
        return -errno.EPERM

    def unlink(self, path):
        return -errno.EPERM
        
    def mknod(self, path, mode, dev):
        return -errno.EPERM

    def open(self, path, flags):
        return 0

    def utimens(self, path, tmp, tmp2):
        return -errno.EPERM

    def read(self, path, size, offset):
        path = path[1:]
        if path not in self.CACHE:
            return -errno.ENOENT
        else:
            if self.CACHE[path].isfile() == True:
                fp = self.tfO.extractfile(self.CACHE[path])
                fp.seek(offset)
                tmp = fp.read(size)
                fp.close()
                return tmp
        return -errno.ENOENT

    def write(self, path, data, offset):
        return -errno.EPERM

    def truncate(self, path, length):
        return -errno.EPERM
        
        
        
        
      
if __name__ == '__main__':  
    fs = MyFS(tar="/home/lwahlmeier/myVids.tar.bz2")
    fs.parse(errex=1)  
    fs.main()  
